package com.datagateway.controller;

import com.datagateway.component.ScriptVersionManager;
import com.datagateway.component.ScriptABTestManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 脚本管理控制器
 * 提供脚本版本管理和A/B测试相关的REST API接口
 * 
 * @author Data Gateway Team
 * @version 1.0.0
 */
@RestController
@RequestMapping("/data-gateway/api/scripts")
public class ScriptManagementController {

    @Autowired
    private ScriptVersionManager scriptVersionManager;

    @Autowired
    private ScriptABTestManager scriptABTestManager;

    /**
     * 创建脚本版本
     * 
     * @param request 创建版本请求
     * @return 操作结果
     */
    @PostMapping("/versions")
    public Map<String, Object> createScriptVersion(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String scriptName = (String) request.get("scriptName");
            String scriptContent = (String) request.get("scriptContent");
            String version = (String) request.get("version");
            String description = (String) request.getOrDefault("description", "");
            
            if (scriptName == null || scriptContent == null || version == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数: scriptName, scriptContent, version");
                return result;
            }
            
            boolean success = scriptVersionManager.createScriptVersion(scriptName, scriptContent, version, description);
            
            result.put("success", success);
            result.put("message", success ? "脚本版本创建成功" : "脚本版本创建失败");
            result.put("scriptName", scriptName);
            result.put("version", version);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "创建脚本版本异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 部署脚本版本
     * 
     * @param scriptName 脚本名称
     * @param version 版本号
     * @return 操作结果
     */
    @PostMapping("/{scriptName}/deploy/{version}")
    public Map<String, Object> deployScriptVersion(@PathVariable String scriptName, @PathVariable String version) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = scriptVersionManager.deployScriptVersion(scriptName, version);
            
            result.put("success", success);
            result.put("message", success ? "脚本版本部署成功" : "脚本版本部署失败");
            result.put("scriptName", scriptName);
            result.put("version", version);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "部署脚本版本异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 回滚脚本版本
     * 
     * @param scriptName 脚本名称
     * @param version 版本号
     * @return 操作结果
     */
    @PostMapping("/{scriptName}/rollback/{version}")
    public Map<String, Object> rollbackScriptVersion(@PathVariable String scriptName, @PathVariable String version) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = scriptVersionManager.rollbackScriptVersion(scriptName, version);
            
            result.put("success", success);
            result.put("message", success ? "脚本版本回滚成功" : "脚本版本回滚失败");
            result.put("scriptName", scriptName);
            result.put("version", version);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "回滚脚本版本异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取活跃脚本版本
     * 
     * @param scriptName 脚本名称
     * @return 活跃版本信息
     */
    @GetMapping("/{scriptName}/active")
    public Map<String, Object> getActiveScriptVersion(@PathVariable String scriptName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptVersionManager.ScriptVersion activeVersion = scriptVersionManager.getActiveScriptVersion(scriptName);
            
            if (activeVersion != null) {
                result.put("success", true);
                result.put("activeVersion", activeVersion);
            } else {
                result.put("success", false);
                result.put("message", "未找到活跃脚本版本");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取活跃脚本版本异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取脚本版本
     * 
     * @param scriptName 脚本名称
     * @param version 版本号
     * @return 版本信息
     */
    @GetMapping("/{scriptName}/versions/{version}")
    public Map<String, Object> getScriptVersion(@PathVariable String scriptName, @PathVariable String version) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptVersionManager.ScriptVersion scriptVersion = scriptVersionManager.getScriptVersion(scriptName, version);
            
            if (scriptVersion != null) {
                result.put("success", true);
                result.put("scriptVersion", scriptVersion);
            } else {
                result.put("success", false);
                result.put("message", "脚本版本不存在");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取脚本版本异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取脚本所有版本
     * 
     * @param scriptName 脚本名称
     * @return 版本列表
     */
    @GetMapping("/{scriptName}/versions")
    public Map<String, Object> getScriptVersions(@PathVariable String scriptName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ScriptVersionManager.ScriptVersion> versions = scriptVersionManager.getScriptVersions(scriptName);
            
            result.put("success", true);
            result.put("versions", versions);
            result.put("count", versions.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取脚本版本列表异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 开始A/B测试
     * 
     * @param request A/B测试请求
     * @return 操作结果
     */
    @PostMapping("/ab-test/start")
    public Map<String, Object> startABTest(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String scriptName = (String) request.get("scriptName");
            String versionA = (String) request.get("versionA");
            String versionB = (String) request.get("versionB");
            Double trafficRatio = ((Number) request.getOrDefault("trafficRatio", 0.5)).doubleValue();
            Integer duration = (Integer) request.getOrDefault("duration", 60);
            
            if (scriptName == null || versionA == null || versionB == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数: scriptName, versionA, versionB");
                return result;
            }
            
            boolean success = scriptABTestManager.startABTest(scriptName, versionA, versionB, trafficRatio, duration);
            
            result.put("success", success);
            result.put("message", success ? "A/B测试开始成功" : "A/B测试开始失败");
            result.put("scriptName", scriptName);
            result.put("versionA", versionA);
            result.put("versionB", versionB);
            result.put("trafficRatio", trafficRatio);
            result.put("duration", duration);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "开始A/B测试异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 停止A/B测试
     * 
     * @param scriptName 脚本名称
     * @param winningVersion 获胜版本
     * @return 操作结果
     */
    @PostMapping("/ab-test/stop/{scriptName}")
    public Map<String, Object> stopABTest(@PathVariable String scriptName, 
                                        @RequestParam(required = false) String winningVersion) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            boolean success = scriptABTestManager.stopABTest(scriptName, winningVersion);
            
            result.put("success", success);
            result.put("message", success ? "A/B测试停止成功" : "A/B测试停止失败");
            result.put("scriptName", scriptName);
            result.put("winningVersion", winningVersion);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "停止A/B测试异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取活跃的A/B测试
     * 
     * @return 活跃测试列表
     */
    @GetMapping("/ab-test/active")
    public Map<String, Object> getActiveABTests() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ScriptABTestManager.ABTestSession> activeTests = scriptABTestManager.getActiveABTests();
            
            result.put("success", true);
            result.put("activeTests", activeTests);
            result.put("count", activeTests.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取活跃A/B测试异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取A/B测试结果
     * 
     * @param scriptName 脚本名称
     * @return 测试结果
     */
    @GetMapping("/ab-test/result/{scriptName}")
    public Map<String, Object> getABTestResult(@PathVariable String scriptName) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptABTestManager.ABTestResult testResult = scriptABTestManager.getABTestResult(scriptName);
            
            if (testResult != null) {
                result.put("success", true);
                result.put("testResult", testResult);
            } else {
                result.put("success", false);
                result.put("message", "A/B测试结果不存在");
            }
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取A/B测试结果异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取所有A/B测试结果
     * 
     * @return 测试结果列表
     */
    @GetMapping("/ab-test/results")
    public Map<String, Object> getAllABTestResults() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            List<ScriptABTestManager.ABTestResult> testResults = scriptABTestManager.getAllABTestResults();
            
            result.put("success", true);
            result.put("testResults", testResults);
            result.put("count", testResults.size());
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取A/B测试结果列表异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 选择脚本版本（用于A/B测试）
     * 
     * @param scriptName 脚本名称
     * @param requestId 请求ID
     * @return 版本选择结果
     */
    @PostMapping("/{scriptName}/select-version")
    public Map<String, Object> selectScriptVersion(@PathVariable String scriptName, 
                                                  @RequestParam String requestId) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptABTestManager.ScriptVersionSelection selection = 
                scriptABTestManager.selectScriptVersion(scriptName, requestId);
            
            result.put("success", true);
            result.put("selection", selection);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "选择脚本版本异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 记录A/B测试结果
     * 
     * @param request 测试结果请求
     * @return 操作结果
     */
    @PostMapping("/ab-test/record")
    public Map<String, Object> recordABTestResult(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            String scriptName = (String) request.get("scriptName");
            String version = (String) request.get("version");
            Boolean success = (Boolean) request.get("success");
            Long processingTime = ((Number) request.getOrDefault("processingTime", 0)).longValue();
            String errorMessage = (String) request.getOrDefault("errorMessage", "");
            
            if (scriptName == null || version == null || success == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数: scriptName, version, success");
                return result;
            }
            
            scriptABTestManager.recordABTestResult(scriptName, version, success, processingTime, errorMessage);
            
            result.put("success", true);
            result.put("message", "A/B测试结果记录成功");
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "记录A/B测试结果异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取脚本版本统计信息
     * 
     * @return 统计信息
     */
    @GetMapping("/statistics/versions")
    public Map<String, Object> getScriptVersionStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptVersionManager.ScriptVersionStatistics stats = scriptVersionManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", stats);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取脚本版本统计异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取A/B测试统计信息
     * 
     * @return 统计信息
     */
    @GetMapping("/statistics/ab-test")
    public Map<String, Object> getABTestStatistics() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptABTestManager.ABTestStatistics stats = scriptABTestManager.getStatistics();
            
            result.put("success", true);
            result.put("statistics", stats);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取A/B测试统计异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 设置脚本版本配置
     * 
     * @param request 配置请求
     * @return 操作结果
     */
    @PostMapping("/config/versions")
    public Map<String, Object> setScriptVersionConfiguration(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Boolean enabled = (Boolean) request.get("enabled");
            String repositoryPath = (String) request.get("repositoryPath");
            Integer maxVersions = (Integer) request.get("maxVersions");
            Integer validationTimeout = (Integer) request.get("validationTimeout");
            Boolean autoBackup = (Boolean) request.get("autoBackup");
            String backupPath = (String) request.get("backupPath");
            
            if (enabled == null || repositoryPath == null || maxVersions == null || 
                validationTimeout == null || autoBackup == null || backupPath == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数");
                return result;
            }
            
            scriptVersionManager.setConfiguration(enabled, repositoryPath, maxVersions, 
                validationTimeout, autoBackup, backupPath);
            
            result.put("success", true);
            result.put("message", "脚本版本配置设置成功");
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置脚本版本配置异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 设置A/B测试配置
     * 
     * @param request 配置请求
     * @return 操作结果
     */
    @PostMapping("/config/ab-test")
    public Map<String, Object> setABTestConfiguration(@RequestBody Map<String, Object> request) {
        Map<String, Object> result = new HashMap<>();
        
        try {
            Boolean enabled = (Boolean) request.get("enabled");
            Integer defaultDuration = (Integer) request.get("defaultDuration");
            Double defaultRatio = ((Number) request.get("defaultRatio")).doubleValue();
            Integer maxConcurrent = (Integer) request.get("maxConcurrent");
            Boolean autoStop = (Boolean) request.get("autoStop");
            Integer errorThreshold = (Integer) request.get("errorThreshold");
            
            if (enabled == null || defaultDuration == null || defaultRatio == null || 
                maxConcurrent == null || autoStop == null || errorThreshold == null) {
                result.put("success", false);
                result.put("message", "缺少必要参数");
                return result;
            }
            
            scriptABTestManager.setConfiguration(enabled, defaultDuration, defaultRatio, 
                maxConcurrent, autoStop, errorThreshold);
            
            result.put("success", true);
            result.put("message", "A/B测试配置设置成功");
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "设置A/B测试配置异常: " + e.getMessage());
        }
        
        return result;
    }

    /**
     * 获取脚本管理概览
     * 
     * @return 概览信息
     */
    @GetMapping("/overview")
    public Map<String, Object> getScriptManagementOverview() {
        Map<String, Object> result = new HashMap<>();
        
        try {
            ScriptVersionManager.ScriptVersionStatistics versionStats = scriptVersionManager.getStatistics();
            ScriptABTestManager.ABTestStatistics abTestStats = scriptABTestManager.getStatistics();
            List<ScriptABTestManager.ABTestSession> activeTests = scriptABTestManager.getActiveABTests();
            
            Map<String, Object> overview = new HashMap<>();
            overview.put("versionStatistics", versionStats);
            overview.put("abTestStatistics", abTestStats);
            overview.put("activeTests", activeTests);
            overview.put("timestamp", System.currentTimeMillis());
            
            result.put("success", true);
            result.put("overview", overview);
            
        } catch (Exception e) {
            result.put("success", false);
            result.put("message", "获取脚本管理概览异常: " + e.getMessage());
        }
        
        return result;
    }
}
